﻿using CodeSHARPer.Model;
using CodeSHARPer.Services;
using CodeSHARPer.ViewModel.Base;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Data;

namespace CodeSHARPer.ViewModel.Tools
{
    public class WorkingFolderViewModel : Base.ToolViewModel
    {
        public const string ToolContentId = "WorkingFolder";
        ICollectionView view;

        public WorkingFolderViewModel()
            : base("Working Folder")
        {
            this.ContentId = ToolContentId;

            //commands
            this.OpenFileFromTreeCommand = new Cinch.SimpleCommand<object, object>(DoOpenFileFromTree);
            this.ReScanFolderCommand = new Cinch.SimpleCommand<object, object>(DoReScanFolder);

            //open the working folder
            this.FolderPath = Workspace.Instance.Config.WorkingFolderFullPath;
        }

        public override Uri IconSource
        {
            get { return new Uri("/Themes/Images/App/Ico/app.working.folder.ico", UriKind.RelativeOrAbsolute); }
        }

        ObservableCollection<FolderRoot> items;

        public ObservableCollection<FolderRoot> Items
        {
            get
            {
                if (items == null)
                    items = new ObservableCollection<FolderRoot>();

                return items;
            }
            set
            {
                items = value;
                NotifyPropertyChanged(ObservableHelper.CreateArgs<WorkingFolderViewModel>(c => c.Items));
            }
        }

        string folderPath;
        public string FolderPath
        {
            get { return folderPath; }
            set
            {
                if (string.IsNullOrEmpty(value) == false && Directory.Exists(value))
                {
                    folderPath = value;
                    ReloadFolders(folderPath);
                }
            }
        }

        private void ReloadFolders(string path = "")
        {
            Items.Clear();
            if (string.IsNullOrEmpty(path) == false)
                Items.Add(FolderRoot.GetWorkingFolder(path: path, showFiles: true));

            view = CollectionViewSource.GetDefaultView(Items);
            view.Filter = FilterFiles;
        }

        #region Commands
        public Cinch.SimpleCommand<object, object> OpenFileFromTreeCommand { get; set; }
        internal void DoOpenFileFromTree(object args)
        {
            Cinch.EventToCommandArgs eventArgs = args as Cinch.EventToCommandArgs;
            if (eventArgs != null)
            {
                FolderItem item = eventArgs.CommandParameter as FolderItem;
                if (item != null && File.Exists(item.FullPath))
                    Workspace.Instance.Open(item.FullPath, true);
            }
        }

        public Cinch.SimpleCommand<object, object> ReScanFolderCommand { get; set; }
        internal void DoReScanFolder(object args)
        {
            ReloadFolders(this.FolderPath);
        }
        #endregion

        string filterString;
        public string FilterString
        {
            get { return filterString; }
            set
            {
                filterString = value;
                NotifyPropertyChanged(ObservableHelper.CreateArgs<WorkingFolderViewModel>(c => c.FilterString));
                //refresh the items
                view.Refresh();
                //refresh the children if each item
                foreach (var item in this.items)
                {
                    SetFilter(item);
                }
            }
        }

        private bool FilterFiles(object filter)
        {
            FolderItem folder = filter as FolderItem;
            if (folder != null)
            {
                if (folder.Children != null)
                {
                    ICollectionView viewChildren = CollectionViewSource.GetDefaultView(folder.Children);
                    if (string.IsNullOrEmpty(FilterString) == false)
                        viewChildren.Filter = (c =>
                            (c as FolderItem).FullPath.IndexOf(FilterString, 0, StringComparison.OrdinalIgnoreCase) >= 0);
                    else
                        viewChildren.Filter = (c => true);

                    foreach (var item in folder.Children.Where(c => c.HasChildren))
                    {
                        FilterFiles(item);
                    }
                }

                //return folder.FullPath.IndexOf(FilterString, 0, StringComparison.OrdinalIgnoreCase) > 0;
            }

            return true;
        }

        private void SetFilter(FolderItem folder)
        {
            foreach (FolderItem folderChild in folder.Children)
            {
                folderChild.FilterString = this.FilterString;
                if (folderChild.HasChildren)
                    SetFilter(folderChild);
            }
        }
    }
}
